package com.powergisol.gis.model;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.*;

/**
 * RAS非对称加密
 */
public class RASUtils {
    /**
     * * 生成密钥对 *
     * @return KeyPair
     */
    public static KeyPair generateKeyPair() {

        KeyPairGenerator keyPairGen = null;
        KeyPair keyPair = null;
        try {
            keyPairGen = KeyPairGenerator.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider()); //生成公钥私钥（加密算法，提供者）
            final int KEY_SIZE = 1024;// 没什么好说的了，这个值关系到块加密的大小，可以更改，但是不要太大，否则效率会低
            keyPairGen.initialize(KEY_SIZE, new SecureRandom());//使用给定的随机源（以及默认参数集）初始化某个密钥大小的密钥对生成器。
            keyPair = keyPairGen.generateKeyPair();//生成密钥对。
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return keyPair;

    }



    /**
     * * 解密 *
     * @param pk 解密的密钥 *
     * @param raw 已经加密的数据 *
     * @return 解密后的明文 *
     */
    public static byte[] decrypt(PrivateKey pk, byte[] raw) {
        Cipher cipher = null;
        ByteArrayOutputStream bout=null;
        try {
            cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
            cipher.init(Cipher.DECRYPT_MODE, pk);
            int blockSize = cipher.getBlockSize();
            bout = new ByteArrayOutputStream(64);
            int j = 0;
            while (raw.length - j * blockSize > 0) {
                bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
                j++;
            }
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | InvalidKeyException | IOException | BadPaddingException e) {
            e.printStackTrace();
        }
        assert bout != null;
        return bout.toByteArray();
    }

    /**
     * 16进制 To byte[]
     * @param hexString
     * @return byte[]
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    /**
     * Convert char to byte
     * @param c char
     * @return byte
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }
}


